package com.zmn.mcc.business.impl.module;

import com.alibaba.fastjson.JSONObject;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.manager.common.database.annotation.ReadOnlyConnection;
import com.zmn.mcc.business.interfaces.module.ModuleBService;
import com.zmn.mcc.model.entity.module.McModule;
import com.zmn.mcc.model.entity.module.McModuleQuery;
import com.zmn.mcc.model.entity.permit.McPermit;
import com.zmn.mcc.model.entity.sys.McSys;
import com.zmn.mcc.services.interfaces.module.ModuleService;
import com.zmn.mcc.services.interfaces.permit.PermitService;
import com.zmn.mcc.services.interfaces.sys.SysService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author heguanghua
 * @since 2020/04/14 22:20
 */
@Service
public class ModuleBServiceImpl implements ModuleBService {
    protected Logger logger = LoggerFactory.getLogger(ModuleBServiceImpl.class);

    @Resource
    private ModuleService moduleService;
    @Resource
    private SysService sysService;
    @Resource
    private PermitService permitService;


    // region 取得全部系统的模块列表

    @Override
    @ReadOnlyConnection
    public List<McModule> listModule(Integer level, Integer status) {

        List<McModule> items = new ArrayList<>();

        List<McSys> syses = sysService.listAll(status);
        syses.forEach(item -> {
            McModule module = new McModule();
            module.setModuleId(item.getSysId() >= 1000 ? item.getSysId() - 500 : item.getSysId());  // 系统id与模块id重复，导致bug，临时解决：-500；否则重新设计
            module.setModuleName(item.getSysName());
            module.setParentId(0);
            module.setSysId(item.getSysId());
            module.setLevel(0);
            module.setSort(item.getSort());
            module.setStatus(item.getStatus());
            items.add(module);
        });

        McModuleQuery query = new McModuleQuery();
        query.setStatus(status);
        List<McModule> modules = moduleService.listByQuery(query);
        for (McModule module : modules) {
            if (level != null && module.getLevel() != null && module.getLevel() > level) {
                continue;
            }
            // 如果模块的父ID为1，则更改为系统ID，此处注意，系统主键ID必须都小于模块ID
            if (module.getParentId() == GlobalConsts.TOP_ID) {
                module.setParentId(module.getSysId() >= 1000 ? module.getSysId() - 500 : module.getSysId());  // 系统id与模块id重复，导致bug，临时解决：-500；否则重新设计
            }
            items.add(module);
        }

        return items;
    }
    // endregion

    // region 取得指定系统的模块列表

    @Override
    @ReadOnlyConnection
    public List<McModule> listModule(Integer sysId, Integer level, Integer status) {

        List<McModule> items = moduleService.listBySysId(sysId, status);

        Integer l = level == null ? 100 : level;
        return items.stream().filter(item -> {
            if (item.getLevel() == null) {
                return true;
            }
            return item.getLevel() <= l;
        }).collect(Collectors.toList());
    }
    // endregion


    // region 取得层级模块列表

    @Override
    @ReadOnlyConnection
    public List<McModule> listModuleTree(Integer level, Integer status) {
        List<McModule> modules = new ArrayList<>();
        List<McSys> syses = sysService.listAll(status);
        syses.forEach(item -> {
            McModule module = new McModule();
            module.setModuleId(item.getSysId());
            module.setModuleName(item.getSysName());
            module.setParentId(0);
            module.setSysId(item.getSysId());
            module.setLevel(0);
            module.setSort(item.getSort());
            module.setStatus(item.getStatus());
            module.setModules(this.listModuleTree(item.getSysId(), level, status));
            modules.add(module);
        });
        return modules;
    }

    @Override
    @ReadOnlyConnection
    public List<McModule> listModuleTree(Integer sysId, Integer level, Integer status) {
        List<McModule> modules = moduleService.listByParentId(sysId, GlobalConsts.TOP_ID, status);
        modules.forEach(item -> {
            this.buildMenuTrees(item, level, status, 1);
        });
        return modules;
    }

    private void buildMenuTrees(McModule module, Integer level, Integer status, Integer levelIndex) {
        if (level != null && levelIndex >= level) {
            return;
        }
        List<McModule> modules = moduleService.listByParentId(module.getSysId(), module.getModuleId(), status);
        modules.forEach(item -> {
            module.getModules().add(item);
            this.buildMenuTrees(item, level, status, levelIndex + 1);
        });
        return;
    }
    // endregion

    // region 新增/修改模块

    @Override
    public ResponseDTO addModule(McModule module) {

        try {

            // 校验
            ResponseDTO checkResult = this.checkModule(module);
            if (!checkResult.isSuccess()) {
                return checkResult;
            }

            // 初始化
            this.initModule(module);

            // 模块信息
            moduleService.insert(module);

            //region 添加默认权限

            McPermit permit = new McPermit();
            permit.setModuleId(module.getModuleId());
            permit.setSysId(module.getSysId());
            permit.setUpdater(module.getUpdater());
            permit.setUpdateTime(module.getUpdateTime());
            permit.setCreater(module.getUpdater());
            permit.setCreateTime(module.getUpdateTime());

            // 列表
            permit.setPermitName("列表/查询");
            permit.setUrl(module.getModuleCode() + "/list.action");
            permitService.insert(permit);

            // 详情
            permit.setPermitName("详情");
            permit.setUrl(module.getModuleCode() + "/detail.action");
            permitService.insert(permit);

            // 新增/编辑
            permit.setPermitName("新增/修改");
            permit.setUrl(module.getModuleCode() + "/modify/addEdit.action");
            permitService.insert(permit);

            // 启用/停用
            permit.setPermitName("启用/停用");
            permit.setUrl(module.getModuleCode() + "/modify/modifyStatus.action");
            permitService.insert(permit);

            // 修改排序
            permit.setPermitName("排序");
            permit.setUrl(module.getModuleCode() + "/modify/modifySort.action");
            permitService.insert(permit);
            // endregion

            return ResponseDTO.success(module.getModuleId(), "新增模块成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]新增模块失败,module:[%s],ex:[%s]", JSONObject.toJSONString(module), ex.getMessage()));
            return ResponseDTO.fail("新增模块失败");
        }
    }

    @Override
    public ResponseDTO modifyModule(McModule module) {

        try {

            // 校验
            ResponseDTO checkResult = this.checkModule(module);
            if (!checkResult.isSuccess()) {
                return checkResult;
            }

            // 初始化
            this.initModule(module);

            // 模块信息
            moduleService.updateByKey(module);

            return ResponseDTO.success(module.getModuleId(), "修改模块成功");

        } catch (Exception ex) {
            logger.error(String.format("[ZMN]修改模块失败,module:[%s],ex:[%s]", JSONObject.toJSONString(module), ex.getMessage()));
            return ResponseDTO.fail("修改模块失败");
        }
    }

    /**
     * 校验模块信息
     *
     * @param module
     * @return
     */
    private ResponseDTO checkModule(McModule module) {

        if (StringUtil.isBlank(module.getModuleName())) {
            return ResponseDTO.fail("模块名称不能为空");
        }
        if (StringUtil.isBlank(module.getModuleCode())) {
            return ResponseDTO.fail("模块代码及路径不能为空");
        }
        if (NumberUtil.isNullOrZero(module.getSysId())) {
            return ResponseDTO.fail("未指定系统");
        }

        return ResponseDTO.success(null, "OK");
    }

    /**
     * 初始化模块
     *
     * @param module
     */
    private void initModule(McModule module) {

        // 模块代码及路径
        if (!module.getModuleCode().startsWith("/")) {
            module.setModuleCode("/" + module.getModuleCode());
        }
        if (module.getModuleCode().endsWith("/")) {
            module.setModuleCode(module.getModuleCode().substring(0, module.getModuleCode().length() - 1));
        }

        // 模块层级
        Integer level = 0;
        if (NumberUtil.isNotNullOrZero(module.getParentId()) && module.getParentId() > GlobalConsts.TOP_ID) {
            McModule parent = moduleService.findByKey(module.getParentId());
            level = Optional.ofNullable(parent.getLevel()).orElse(GlobalConsts.TOP_ID);
            level += 1;
        } else {
            level = GlobalConsts.TOP_ID;
        }
        module.setLevel(level);
    }
    // endregion
}
